/**
 * RecvHeartBeat.java
 * 版权所有(C) 2013
 * 创建者:cuiran 2013-11-27 上午10:58:02
 */
package com.ghyf.mplay.net.common;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;


import android.content.Context;
import android.content.Intent;

import com.example.watchdog.Temhum;
import com.ghyf.mplay.application.CookieConstants;
import com.ghyf.mplay.application.UserInfoSingleton;
import com.ghyf.mplay.net.data.ConfigFtpData;
import com.ghyf.mplay.util.LogUtil;
import com.ghyf.mplay.value.ConstantValue;

/**
 *  
 * 心跳 <br>
 * 控制器服务程序定时向控制器发送CMD.HEART.REQUEST报文，<br>
 * 控制器收到该报文后，返回CMD.HEART.REPORT报文
 * @author cuiran
 * @version 1.0.0
 */
public class RecvHeartBeat extends RecvBase implements Runnable {

	public RecvHeartBeat(int listenPort, int serverPort,Context context){
		port_listen = listenPort;
		port_server = serverPort;
		mContext=context;
	}
	public void updatetime(int time ){
		 LogUtil.i(TAG, "RecvHeartBeat  -- updatetime ="+time);
		 long t=time*1000l;
		String timestr = String.valueOf(t);
		Intent myIntent = new Intent(ConstantValue.TIME_RECEIVER);  
		myIntent.putExtra("time", timestr);
        myIntent.setAction(ConstantValue.TIME_RECEIVER);  
        mContext.sendBroadcast(myIntent);  
        LogUtil.i(TAG, "RecvHeartBeat  -- updatetime"+timestr);
        UserInfoSingleton.isUpdate=false;
	}
	private Temhum temhum=null;
	int i=0;
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run()
	{
		LogUtil.i(TAG, "RecvHeartbeat.run() -- start!");
		try
		{
//			LogUtil.i(TAG, "RecvHeartbeat.run() -- try....");
			temhum=new Temhum();
			DatagramSocket so_out = new DatagramSocket();
			DatagramSocket so_in = new DatagramSocket(port_listen);
			LogUtil.i(TAG, "RecvHeartbeat.run() -- Recv Socket Created!");
			so_in.setSoTimeout(100);
			
			byte[] buf_in = new byte[GData.maxPacketLength];
			DatagramPacket pkt_in = new DatagramPacket(buf_in, buf_in.length);
			LogUtil.i(TAG, "RecvHeartbeat.run() -- Recv Pakcet Created!");
			
			while(!isStop)
			{
				try
				{
					so_in.receive(pkt_in);
					LogUtil.i(TAG, "RecvHeartbeat.run() -- Recv PacketLength(" + pkt_in.getLength() + ")");
					// Check Packet Length
					int recvLength = pkt_in.getLength();
					if(recvLength < packetHeaderLength)
					{
						LogUtil.i(TAG, "RecvHeartbeat.run() -- Received bad Packet, Length=" + recvLength);
						continue;
					}
					
					// Analyse the Packet Header
					byte[] buf_recv = pkt_in.getData();
					assert(buf_recv.length == recvLength);
					ByteArrayInputStream baInPacketHeader = new ByteArrayInputStream(buf_recv, 0, packetHeaderLength);
					DataInputStream din = new DataInputStream(baInPacketHeader);
					byte stx = din.readByte();
					short cmdID = din.readShort();
					
					switch(cmdID){
						case CMD_HEART_REQUEST:
						{
							int timestamp = din.readInt();
							
							if(UserInfoSingleton.isUpdate){
								updatetime(timestamp);
							}
							int tickCount = din.readInt();
							byte[] buf_temp = new byte[recvLength];
							din.read(buf_temp, 0, deviceIDLength);
							String deviceID = new String(buf_temp, 0, deviceIDLength,charset);
							din.skipBytes(packetHeaderReservedLength);
							short dataLength = din.readShort();
							
							// Check & LogUtil
							if(stx != STX_SERVER2CLIENT || cmdID != CMD_HEART_REQUEST || dataLength != 0)
							{
								LogUtil.i(TAG, "RecvHeartbeat.run() -- Received BAD Packet, stx=" + stx + " cmdID=" + cmdID + 
										" timestamp=" + timestamp + " tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);
								continue;
							}
							/**
							 * 这里进行判断 如果心跳连接 说明服务器网络恢复 继续未完成的下载
							 */
							boolean isDownloadFail=UserInfoSingleton.getBoolean(CookieConstants.IsDownloadFail,false);
							if(isDownloadFail){
								ConfigFtpData ftpData=(ConfigFtpData)UserInfoSingleton.readObject(CookieConstants.ConfigFtpData);
							    Intent myIntent = new Intent(ConstantValue.CMD_RECEIVER);  
					            myIntent.putExtra(ConstantValue.EXTRA_TYPE, ftpData.getCmdId());
					            myIntent.putExtra(ConstantValue.EXTRA_OBJ, ftpData);
					            myIntent.setAction(ConstantValue.CMD_RECEIVER);  
					            mContext.sendBroadcast(myIntent);  
							}
//							LogUtil.i(TAG, "RecvHeartbeat.run() -- Received Heartbeat Packet, stx=" + stx + " cmdID=" + cmdID + 
//									" timestamp=" + timestamp + "tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);
							
							// Get server address
							InetAddress inetAddr_in = pkt_in.getAddress();
							
							String ip_in = inetAddr_in.getHostAddress();
							int port_in = pkt_in.getPort();
							
							// make a DatagramPacket for sendto server, we use port_server instead of port_in
							int temp=temhum.getTem();
							byte[] buf_out = makeHeartbeatPacket(temp);
//							DatagramPacket pkt_out = new DatagramPacket(buf_out, buf_out.length, inetAddr_in, port_in);
							DatagramPacket pkt_out = new DatagramPacket(buf_out, buf_out.length, inetAddr_in, port_server);
							// send packet
					        so_out.send(pkt_out);
//							LogUtil.i(TAG, "RecvHeartbeat.run() -- Recv Packet from: IP(" + ip_in + ":" + port_in + ") Length(" + pkt_in.getLength() + ")");
//						 
					        LogUtil.i(TAG, "RecvHeartbeat.run() -- Send Packet to: ip_in("+ip_in+") port_in("+port_in+") port_server("+port_server+") temp("+temp+") Length(" + pkt_out.getLength() + ")");
						}
						break;
						case CMD_HEART_REQUEST2:
						{
							int timestamp = din.readInt();
							
							int tickCount = din.readInt();
							byte[] buf_temp = new byte[recvLength];
							din.read(buf_temp, 0, deviceIDLength);
							String deviceID = new String(buf_temp, 0, deviceIDLength,charset);
							din.skipBytes(packetHeaderReservedLength);
							short dataLength = din.readShort();
							
							// Check & LogUtil
							if(stx != STX_SERVER2CLIENT || cmdID != CMD_HEART_REQUEST2 || dataLength != 0)
							{
								LogUtil.i(TAG, "RecvHBeat.run() -- Received BAD Packet, stx=" + stx + " cmdID=" + cmdID + 
										" timestamp=" + timestamp + " tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);
								continue;
							}
//							LogUtil.i(TAG, "RecvHBeat.run() -- Received Heartbeat Packet, stx=" + stx + " cmdID=" + cmdID + 
//									" timestamp=" + timestamp + "tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);
//							
							// Get server address
							InetAddress inetAddr_in = pkt_in.getAddress();
//							String ip_in = inetAddr_in.getHostAddress();
							int port_in = pkt_in.getPort();
							
//							LogUtil.i(TAG, "RecvHBeat.run() -- Recv Packet from: IP(" + ip_in + ":" + port_in + ") Length(" + pkt_in.getLength() + ")");
							
							// make a DatagramPacket for sendto server, we use port_server instead of port_in
							byte[] buf_out = makeHeartbeatPacket2();
							DatagramPacket pkt_out = new DatagramPacket(buf_out, buf_out.length, inetAddr_in, port_in);
//							DatagramPacket pkt_out = new DatagramPacket(buf_out, buf_out.length, inetAddr_in, port_server);
							// send packet
					        so_out.send(pkt_out);
//					        LogUtil.i(TAG, "RecvHBeat.run() -- Send Packet to: IP(" + ip_in + ":" + port_server + ") Length(" + pkt_out.getLength() + ")");
						}
							
							break;
					}
					
				
				}
				catch(IOException e)
				{
			//		e.equals(IOException.)
			//		LogUtil.i(TAG, "RecvHeartbeat.run() -- catch IOException: receive() " + e.getMessage());
				}
				finally
				{
			//		LogUtil.i(TAG, "RecvHeartbeat.run() -- finally !!");
				}
			}
			so_in.close();
	        so_out.close();
		}
		catch (SocketException e)
		{ 
			LogUtil.i(TAG, "RecvHeartbeat.run() -- catch SocketException: " + e.getLocalizedMessage());
        }
		catch(Exception e)
		{
			LogUtil.e(TAG, "RecvHeartbeat.run() -- catch Exception: " , e);
		}
		finally
		{
		}	
		LogUtil.i(TAG, "RecvHeartbeat.run() -- exit!");	
	}

}
